#pragma once
#include<queue>
#include<iostream>
#include<unistd.h>
#include<pthread.h>
using std::cout;
using std::endl;
template<class T>
class BlockQueue{
    static const int defaultnum = 5;
public:
    BlockQueue(int maxcap = defaultnum)
            :_maxcap(maxcap)
    {
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&c_cond,nullptr);
        pthread_cond_init(&p_cond,nullptr);
    }
    T pop()
    {
        pthread_mutex_lock(&_mutex);
        if(_q.size() == 0)
        {
            cout << "队列为空!需要生产者生产" << endl;
            pthread_cond_wait(&c_cond,&_mutex);          
        }
        T f= _q.front();
        _q.pop();
        pthread_cond_signal(&p_cond); 
        pthread_mutex_unlock(&_mutex);
        return f;
    }
    void push(const T& x)
    {
        pthread_mutex_lock(&_mutex);
        // assert(_q.size() < _maxcap);
        if(_q.size() == _maxcap)
        {
            std::cout << "队列已满!需要消费者购买" << std::endl;
            pthread_cond_wait(&p_cond,&_mutex);

            //调用的时候,自动释放锁
        }

        _q.push(x);
        pthread_cond_signal(&c_cond);
        pthread_mutex_unlock(&_mutex);
    }
    ~BlockQueue()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&c_cond);
        pthread_cond_destroy(&p_cond);
    }
    int size()
    {
        return _q.size();
    }

private:
    std::queue<T> _q;//共享资源
    int _maxcap; //极大值
    pthread_mutex_t _mutex;
    pthread_cond_t c_cond;
    pthread_cond_t p_cond;

    int lower_water; //可以在这个范围内生产和消费,push和pop去调整消费策略
    int high_water; 
};